﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace new_problem
{
    class SurfaceSet
    {
        public static readonly Int32 N = 50;
        public static readonly Double sigma = 1.0;
        public static readonly Double h = 15.0;
        public static readonly Double F = 6.67384;

        public static Double[,] GetSurfaceGrid(Double[] x, Double[] y, int k)
        {
            Double[,] result = new Double[N + 1, N + 1];
            switch (k)
            {
                case 0:
                    for (int i = 0; i <= N; i++)
                        for (int j = 0; j <= N; j++)
                            result[i, j] = SurfacePoint0(x[i], y[j]);
                    break;
                case 1:
                    for (int i = 0; i <= N; i++)
                        for (int j = 0; j <= N; j++)
                            result[i, j] = SurfacePoint1(x[i], y[j]);
                    break;
                case 2:
                    for (int i = 0; i <= N; i++)
                        for (int j = 0; j <= N; j++)
                            result[i, j] = SurfacePoint2(x[i], y[j]);
                    break;
                case 3:
                    for (int i = 0; i <= N; i++)
                        for (int j = 0; j <= N; j++)
                            result[i, j] = SurfacePoint3(x[i], y[j]);
                    break;
                case 4:
                    for (int i = 0; i <= N; i++)
                        for (int j = 0; j <= N; j++)
                            result[i, j] = SurfacePoint4(x[i], y[j]);
                    break;
                case 5:
                    for (int i = 0; i <= N; i++)
                        for (int j = 0; j <= N; j++)
                            result[i, j] = SurfacePoint5(x[i], y[j]);
                    break;
                case 6:
                    for (int i = 0; i <= N; i++)
                        for (int j = 0; j <= N; j++)
                            result[i, j] = SurfacePoint6(x[i], y[j]);
                    break;
                default:
                    Console.WriteLine("Default case");
                    break;
            }
            return result;
        }

        public static Double SurfacePoint0(Double x, Double y)
        {
            x -= 5;
            y -= 5;
            return -h + Math.Sin((x / 5) * Math.PI / N) * Math.Sin((y / 5) * Math.PI / N);
        }

        public static Double SurfacePoint1(Double x, Double y)
        {
            x -= 5;
            y -= 5;

            if (x <= 170 && x >= 80 && y <= 170 && y >= 80)
            {
                return -h + 2;
            }
            else return -h;
        }

        public static Double SurfacePoint2(Double x, Double y)
        {
            x -= 20;
            y -= 20;
            if (x <= 60 && y <= 60)
            {
                if (x >= 0 && y >= 0)
                    return -h + 5 * Math.Sin(4 * (x / 5) * Math.PI / N) * Math.Sin(4 * (y / 5) * Math.PI / N);
                else return -h;
            }
            else if (x >= 105 && y >= 105)
            {
                if (x <= 230 && y <= 230)
                    return -h + Math.Sin(2 * ((x + 20) / 5) * Math.PI / N) * Math.Sin(2 * ((y + 20) / 5) * Math.PI / N) *
                           Math.Exp(x * y * Math.PI / (N * N * 25));
                else return -h;
            }
            else
                return -h;
        }

        public static Double SurfacePoint3(Double x, Double y)
        {
            x -= 20;
            y -= 20;
            if (x <= 60 && y <= 60)
            {
                if (x >= 0 && y >= 0)
                    return -h + 5 * Math.Sin(4 * (x / 5) * Math.PI / N) * Math.Sin(4 * (y / 5) * Math.PI / N);
                else return -h;
            }
            else if (x >= 105 && y >= 105)
            {
                if (x <= 230 && y <= 230)
                    return -h - Math.Sin(2 * ((x + 20) / 5) * Math.PI / N) * Math.Sin(2 * ((y + 20) / 5) * Math.PI / N) *
                           Math.Exp(x * y * Math.PI / (N * N * 25));
                else return -h;
            }
            else
                return -h;
        }

        public static Double SurfacePoint4(Double x, Double y)
        {
            x -= 5;
            y -= 5;

            if (x <= 220 && x >= 30 && y <= 220 && y >= 30)
            {
                if (x <= 170 && x >= 80 && y <= 170 && y >= 80)
                {
                    if (x <= 140 && x >= 110 && y <= 140 && y >= 110)
                        return -h + 2;
                    else return -h + 1;
                }
                else return -h - 1;
            }
            else return -h;
        }

        public static Double SurfacePoint5(Double x, Double y)
        {
            x -= 65;
            y -= 130;

            double z = -0.7 * Math.Sqrt(x - (y * y / 81.0));
            if (z < 0 && x < 170)
                return -h + z;
            else return -h;
        }

        public static Double SurfacePoint6(Double x, Double y)
        {
            x -= 5;
            y -= 5;

            if (x <= 130 && x >= 50 && y <= 130 && y >= 50)
            {
                if (x < 110 && y < 110)
                    return -h + 3;
                else return -h + 1;
            }
            else if (x <= 220 && x >= 170 && y <= 220 && y >= 170)
                return -h + 1.2;
            else return -h;
        }
    }
}
